package com.example.listen;

import com.example.entity.OrderInfo;
import com.example.mapper.OrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

/**
 * @author mingtian
 * @version V1.0
 * @Description redis key 失效监听事件
 * @date 2019/11/19 22:16
 */
@Slf4j
@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

    /**
     * 订单前缀
     */
    public static final String ORDER_PREFIX = "order_";
    /**
     * 未支付
     */
    private static final Integer ORDER_UNPAY = 0;

    /**
     * 已支付
     */
    private static final Integer ORDER_PAY = 1;

    /**
     * 过期
     */
    private static final Integer ORDER_EXPIRE = 2;

    @Autowired
    private OrderMapper orderMapper;

    /**
     * Creates new {@link MessageListener} for {@code __keyevent@*__:expired} messages.
     *
     * @param listenerContainer must not be {@literal null}.
     */
    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }


    /**
     * key 失效回调方法
     * 使用场景：在秒杀抢购的时候下单如果订单一直未支付的情况下，默认下单30分钟之后订单未支付，该订单就会进行超时处理。
     * 下单成功之后，库存-1，订单状态为待支付状态；
     * 如果订单半个小时未支付 则自动修改订单状态修改为已超时，然后该商品库存+1.
     *
     * @param message
     * @param pattern
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        log.info("messageBody:{},messageChannel:{}", message.getBody(), message.getChannel());
        //1.获取 失效 key
        String expireKey = message.toString();
        //2.判断 key 是否时订单对应的,避免都去查询数据库
        if (expireKey.contains(ORDER_PREFIX)) {
            OrderInfo orderInfo = orderMapper.getOrderByOrderToken(expireKey);
            if (orderInfo != null && orderInfo.getOrderStatus().equals(ORDER_UNPAY)) {
                int update = orderMapper.update(expireKey, ORDER_EXPIRE);
                log.info("token.expire,key:{},update.result:{}", expireKey, update);
            }
        }
        //3.库存+1 操作
        return;
    }
}
